import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:dio/dio.dart';
import '../models/account.dart';
import '../models/show.dart';
import '../models/platform_config.dart';
import '../providers/ticket_hunter_provider.dart';
import '../utils/logger.dart';
import '../utils/device_utils.dart';
import 'signature_service.dart';
import 'behavior_simulation_service.dart';

/// 猫眼电影抢票服务
class MaoyanTicketService {
  final Dio _dio = Dio();
  final SignatureService _signatureService = SignatureService();
  final BehaviorSimulationService _behaviorService = BehaviorSimulationService();
  final PlatformConfig _config = PlatformConfig.maoyan;
  
  MaoyanTicketService() {
    _setupDio();
  }

  void _setupDio() {
    _dio.options = BaseOptions(
      baseUrl: _config.baseUrl,
      connectTimeout: const Duration(seconds: 8),
      receiveTimeout: const Duration(seconds: 15),
      headers: _config.headers,
    );

    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) async {
        await _behaviorService.randomDelay();
        AppLogger.debug('Maoyan request: ${options.method} ${options.uri}');
        handler.next(options);
      },
      onResponse: (response, handler) {
        AppLogger.debug('Maoyan response: ${response.statusCode}');
        handler.next(response);
      },
      onError: (error, handler) {
        AppLogger.error('Maoyan request error: ${error.message}', error);
        handler.next(error);
      },
    ));
  }

  /// 提交订单
  Future<HuntingResult> submitOrder({
    required Account account,
    required Show show,
    required TicketSku sku,
    required Map<String, dynamic> params,
  }) async {
    try {
      AppLogger.info('Maoyan submitting order for: ${account.username}, show: ${show.name}');
      
      // 第一步：获取电影详情和场次信息
      final movieDetail = await _getMovieDetail(show.itemId);
      if (movieDetail == null) {
        return HuntingResult(
          success: false,
          message: '获取电影详情失败',
          timestamp: DateTime.now(),
        );
      }

      // 第二步：选择场次和座位
      final seatResult = await _selectSeats(
        account: account,
        show: show,
        sku: sku,
        movieDetail: movieDetail,
        params: params,
      );

      if (!seatResult.success) {
        return HuntingResult(
          success: false,
          message: seatResult.message,
          timestamp: DateTime.now(),
          isBlocked: seatResult.isBlocked,
        );
      }

      // 第三步：创建订单
      final orderResult = await _createOrder(
        account: account,
        show: show,
        sku: sku,
        seatData: seatResult.data!,
        params: params,
      );

      return HuntingResult(
        success: orderResult.success,
        message: orderResult.message,
        orderId: orderResult.orderId,
        timestamp: DateTime.now(),
        isBlocked: orderResult.isBlocked,
        metadata: {
          'movieDetail': movieDetail,
          'seatResult': seatResult.data,
          'orderResult': orderResult.data,
        },
      );
    } catch (e) {
      AppLogger.error('Maoyan submit order failed', e);
      return HuntingResult(
        success: false,
        message: '猫眼抢票异常: $e',
        timestamp: DateTime.now(),
      );
    }
  }

  /// 获取电影详情
  Future<Map<String, dynamic>?> _getMovieDetail(String movieId) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final deviceId = await DeviceUtils.generateDeviceId();
      
      final params = {
        'movieId': movieId,
        'timestamp': timestamp.toString(),
      };

      final signature = await _generateMaoyanSignature(params, deviceId);
      
      final response = await _dio.get(
        _config.apiEndpoints['movieDetail']!,
        queryParameters: {
          ...params,
          'sign': signature,
        },
        options: Options(
          headers: await _buildMaoyanHeaders(deviceId, timestamp),
        ),
      );

      if (response.statusCode == 200 && response.data['status'] == 0) {
        return response.data['data'];
      }

      return null;
    } catch (e) {
      AppLogger.error('Get movie detail failed', e);
      return null;
    }
  }

  /// 选择座位
  Future<MaoyanOperationResult> _selectSeats({
    required Account account,
    required Show show,
    required TicketSku sku,
    required Map<String, dynamic> movieDetail,
    required Map<String, dynamic> params,
  }) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      
      // 获取场次信息
      final showInfo = movieDetail['shows']?.firstWhere(
        (s) => s['showId'].toString() == sku.skuId,
        orElse: () => null,
      );

      if (showInfo == null) {
        return MaoyanOperationResult(
          success: false,
          message: '场次信息不存在',
        );
      }

      // 获取座位图
      final seatMapResponse = await _getSeatMap(
        showId: sku.skuId,
        cinemaId: showInfo['cinemaId'].toString(),
        deviceId: account.deviceId,
      );

      if (!seatMapResponse.success) {
        return seatMapResponse;
      }

      // 智能选座
      final selectedSeats = await _intelligentSeatSelection(
        seatMap: seatMapResponse.data!,
        quantity: sku.quantity,
        preferences: params['seatPreferences'] ?? {},
      );

      if (selectedSeats.isEmpty) {
        return MaoyanOperationResult(
          success: false,
          message: '没有可选座位',
        );
      }

      // 锁定座位
      final lockResult = await _lockSeats(
        showId: sku.skuId,
        seats: selectedSeats,
        account: account,
      );

      return lockResult;
    } catch (e) {
      AppLogger.error('Select seats failed', e);
      return MaoyanOperationResult(
        success: false,
        message: '选座失败: $e',
      );
    }
  }

  /// 获取座位图
  Future<MaoyanOperationResult> _getSeatMap({
    required String showId,
    required String cinemaId,
    required String deviceId,
  }) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final params = {
        'showId': showId,
        'cinemaId': cinemaId,
        'timestamp': timestamp.toString(),
      };

      final signature = await _generateMaoyanSignature(params, deviceId);
      
      final response = await _dio.get(
        '/ajax/seat/map',
        queryParameters: {
          ...params,
          'sign': signature,
        },
        options: Options(
          headers: await _buildMaoyanHeaders(deviceId, timestamp),
        ),
      );

      if (response.statusCode == 200 && response.data['status'] == 0) {
        return MaoyanOperationResult(
          success: true,
          message: '获取座位图成功',
          data: response.data['data'],
        );
      }

      return MaoyanOperationResult(
        success: false,
        message: response.data['msg'] ?? '获取座位图失败',
      );
    } catch (e) {
      return MaoyanOperationResult(
        success: false,
        message: '获取座位图异常: $e',
      );
    }
  }

  /// 智能选座算法
  Future<List<Map<String, dynamic>>> _intelligentSeatSelection({
    required Map<String, dynamic> seatMap,
    required int quantity,
    required Map<String, dynamic> preferences,
  }) async {
    final seats = seatMap['seats'] as List? ?? [];
    final availableSeats = seats.where((seat) => 
        seat['status'] == 'available' || seat['status'] == 0).toList();

    if (availableSeats.length < quantity) {
      return [];
    }

    // 按偏好排序座位
    availableSeats.sort((a, b) {
      final scoreA = _calculateSeatScore(a, preferences);
      final scoreB = _calculateSeatScore(b, preferences);
      return scoreB.compareTo(scoreA);
    });

    // 选择连续座位
    final selectedSeats = <Map<String, dynamic>>[];
    
    if (quantity == 1) {
      selectedSeats.add(availableSeats.first);
    } else {
      // 寻找连续座位
      for (int i = 0; i <= availableSeats.length - quantity; i++) {
        final consecutiveSeats = <Map<String, dynamic>>[];
        
        for (int j = 0; j < quantity; j++) {
          final currentSeat = availableSeats[i + j];
          final nextSeat = j < quantity - 1 ? availableSeats[i + j + 1] : null;
          
          consecutiveSeats.add(currentSeat);
          
          // 检查是否连续
          if (nextSeat != null) {
            final currentRow = currentSeat['row'];
            final currentCol = currentSeat['col'];
            final nextRow = nextSeat['row'];
            final nextCol = nextSeat['col'];
            
            if (currentRow != nextRow || nextCol != currentCol + 1) {
              break;
            }
          }
        }
        
        if (consecutiveSeats.length == quantity) {
          selectedSeats.addAll(consecutiveSeats);
          break;
        }
      }
      
      // 如果找不到连续座位，选择评分最高的座位
      if (selectedSeats.isEmpty) {
        selectedSeats.addAll(availableSeats.take(quantity));
      }
    }

    return selectedSeats;
  }

  /// 计算座位评分
  double _calculateSeatScore(Map<String, dynamic> seat, Map<String, dynamic> preferences) {
    double score = 0.0;
    
    final row = seat['row'] as int? ?? 0;
    final col = seat['col'] as int? ?? 0;
    final price = seat['price'] as double? ?? 0.0;
    
    // 中间位置加分
    if (preferences['preferCenter'] == true) {
      final totalCols = preferences['totalCols'] as int? ?? 20;
      final centerDistance = (col - totalCols / 2).abs();
      score += (10 - centerDistance).clamp(0, 10);
    }
    
    // 前排位置加分
    if (preferences['preferFront'] == true) {
      score += (20 - row).clamp(0, 20);
    }
    
    // 价格偏好
    final maxPrice = preferences['maxPrice'] as double?;
    final minPrice = preferences['minPrice'] as double?;
    
    if (maxPrice != null && price <= maxPrice) {
      score += 5;
    }
    if (minPrice != null && price >= minPrice) {
      score += 5;
    }
    
    return score;
  }

  /// 锁定座位
  Future<MaoyanOperationResult> _lockSeats({
    required String showId,
    required List<Map<String, dynamic>> seats,
    required Account account,
  }) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final seatIds = seats.map((s) => s['seatId'].toString()).toList();
      
      final params = {
        'showId': showId,
        'seatIds': seatIds.join(','),
        'timestamp': timestamp.toString(),
      };

      final signature = await _generateMaoyanSignature(params, account.deviceId);
      
      final response = await _dio.post(
        '/ajax/seat/lock',
        data: params,
        options: Options(
          headers: await _buildMaoyanHeaders(account.deviceId, timestamp),
        ),
      );

      if (response.statusCode == 200 && response.data['status'] == 0) {
        return MaoyanOperationResult(
          success: true,
          message: '锁定座位成功',
          data: {
            'seats': seats,
            'lockToken': response.data['data']['lockToken'],
          },
        );
      }

      final message = response.data['msg'] ?? '锁定座位失败';
      final isBlocked = _isMaoyanBlockedError(message);

      return MaoyanOperationResult(
        success: false,
        message: message,
        isBlocked: isBlocked,
      );
    } catch (e) {
      return MaoyanOperationResult(
        success: false,
        message: '锁定座位异常: $e',
      );
    }
  }

  /// 创建订单
  Future<MaoyanOperationResult> _createOrder({
    required Account account,
    required Show show,
    required TicketSku sku,
    required Map<String, dynamic> seatData,
    required Map<String, dynamic> params,
  }) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      
      final orderParams = {
        'showId': sku.skuId,
        'seats': jsonEncode(seatData['seats']),
        'lockToken': seatData['lockToken'],
        'totalPrice': (sku.price * sku.quantity).toString(),
        'timestamp': timestamp.toString(),
      };

      final signature = await _generateMaoyanSignature(orderParams, account.deviceId);
      
      // 模拟人类行为延迟
      await _behaviorService.simulateHumanBehavior('order_create');

      final response = await _dio.post(
        _config.apiEndpoints['orderCreate']!,
        data: orderParams,
        options: Options(
          headers: await _buildMaoyanHeaders(account.deviceId, timestamp),
        ),
      );

      if (response.statusCode == 200 && response.data['status'] == 0) {
        return MaoyanOperationResult(
          success: true,
          message: '创建订单成功',
          orderId: response.data['data']['orderId'],
          data: response.data['data'],
        );
      }

      final message = response.data['msg'] ?? '创建订单失败';
      final isBlocked = _isMaoyanBlockedError(message);

      return MaoyanOperationResult(
        success: false,
        message: message,
        isBlocked: isBlocked,
      );
    } catch (e) {
      return MaoyanOperationResult(
        success: false,
        message: '创建订单异常: $e',
      );
    }
  }

  /// 生成猫眼签名
  Future<String> _generateMaoyanSignature(
    Map<String, dynamic> params,
    String deviceId,
  ) async {
    // 猫眼签名算法（简化版本）
    final sortedKeys = params.keys.toList()..sort();
    final signString = sortedKeys
        .map((key) => '$key=${params[key]}')
        .join('&');
    
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final nonce = Random().nextInt(999999).toString().padLeft(6, '0');
    
    return await _signatureService.generateMaoyanSignature(
      data: signString,
      deviceId: deviceId,
      timestamp: timestamp,
      nonce: nonce,
    );
  }

  /// 构建猫眼请求头
  Future<Map<String, String>> _buildMaoyanHeaders(String deviceId, int timestamp) async {
    final headers = Map<String, String>.from(_config.headers);
    
    headers.addAll({
      'X-Device-ID': deviceId,
      'X-Timestamp': timestamp.toString(),
      'X-App-Version': _config.version,
      'Referer': 'https://m.maoyan.com/',
      'Origin': 'https://m.maoyan.com',
    });

    return headers;
  }

  /// 判断是否被风控
  bool _isMaoyanBlockedError(String message) {
    final blockedKeywords = [
      '风控',
      '限制',
      '异常',
      '封禁',
      '验证',
      'blocked',
      'limit',
      'risk',
      '频繁',
      '稍后再试',
    ];
    
    return blockedKeywords.any((keyword) => 
        message.toLowerCase().contains(keyword.toLowerCase()));
  }

  /// 搜索电影
  Future<List<Map<String, dynamic>>> searchMovies(String keyword) async {
    try {
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final deviceId = await DeviceUtils.generateDeviceId();
      
      final params = {
        'keyword': keyword,
        'timestamp': timestamp.toString(),
      };

      final signature = await _generateMaoyanSignature(params, deviceId);
      
      final response = await _dio.get(
        _config.apiEndpoints['search']!,
        queryParameters: {
          ...params,
          'sign': signature,
        },
        options: Options(
          headers: await _buildMaoyanHeaders(deviceId, timestamp),
        ),
      );

      if (response.statusCode == 200 && response.data['status'] == 0) {
        return List<Map<String, dynamic>>.from(response.data['data']['movies'] ?? []);
      }

      return [];
    } catch (e) {
      AppLogger.error('Search movies failed', e);
      return [];
    }
  }
}

/// 猫眼操作结果
class MaoyanOperationResult {
  final bool success;
  final String message;
  final String? orderId;
  final Map<String, dynamic>? data;
  final bool isBlocked;

  MaoyanOperationResult({
    required this.success,
    required this.message,
    this.orderId,
    this.data,
    this.isBlocked = false,
  });
}